#include "GPS.h"

GPIO_TypeDef* GPS_PORT[GPSnPIN] = { 	GPS_ENABLE_PORT,
									GPS_STANDBY_PORT,
									GPS_RESET_PORT};

const uint16_t GPS_PIN[GPSnPIN] = {	GPS_ENABLE_PIN,
									GPS_STANDBY_PIN,
									GPS_RESET_PIN};

const uint32_t GPS_CLK[GPSnPIN] = {	GPS_ENABLE_CLK,
									GPS_STANDBY_CLK,
									GPS_RESET_CLK};


// UART Receiver buffer
#define GPS_RX_BUFFER_SIZE 128
volatile uint8_t gps_rx_buffer[GPS_RX_BUFFER_SIZE];
volatile unsigned int gps_rx_wr_index,gps_rx_rd_index,gps_rx_counter;

// This flag is set on USART Receiver buffer overflow
volatile uint8_t gps_rx_buffer_overflow;

void GPSInitController(){
	GPIO_InitTypeDef  GPIO_InitStructure;

  /* Enable the GPIO_OUTPUT Clock */ 
	
  	RCC_APB2PeriphClockCmd(GPS_ENABLE_CLK, ENABLE); 
	RCC_APB2PeriphClockCmd(GPS_STANDBY_CLK, ENABLE);
	RCC_APB2PeriphClockCmd(GPS_RESET_CLK, ENABLE);	

	/* Configure the GPS_ENABLE_PIN */
	GPIO_InitStructure.GPIO_Pin = GPS_ENABLE_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  	GPIO_Init(GPS_PORT[GPS_ENABLE], &GPIO_InitStructure);
	
	/* Configure the OUTPUT_GPS_STANDBY_PIN */
	GPIO_InitStructure.GPIO_Pin = GPS_STANDBY_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  	GPIO_Init(GPS_PORT[GPS_STANDBY], &GPIO_InitStructure);

	/* Configure the OUTPUT_GPS_RESET_PIN */
	GPIO_InitStructure.GPIO_Pin = GPS_RESET_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  	GPIO_Init(GPS_PORT[GPS_RESET], &GPIO_InitStructure);
}

void GPS_ENABLE_On(){
	GPS_PORT[GPS_ENABLE]->BRR = GPS_PIN[GPS_ENABLE]; 
}

void GPS_ENABLE_Off(){
	GPS_PORT[GPS_ENABLE]->BSRR = GPS_PIN[GPS_ENABLE]; 
}

void GPS_STANDBY_On(){
	GPS_PORT[GPS_STANDBY]->BRR = GPS_PIN[GPS_STANDBY]; 
}

void GPS_STANDBY_Off(){
	GPS_PORT[GPS_STANDBY]->BSRR = GPS_PIN[GPS_STANDBY]; 
}

void GPS_RESET_On(){
	GPS_PORT[GPS_ENABLE]->BRR = GPS_PIN[GPS_ENABLE]; 
}

void GPS_RESET_Off(){
	GPS_PORT[GPS_ENABLE]->BSRR = GPS_PIN[GPS_ENABLE]; 
}

void UART_GPS_ISR(void){
	uint8_t data;
	if(USART_GetITStatus(COM_GPS, USART_IT_RXNE) != RESET)
	{
		data = USART_ReceiveData(COM_GPS);
		gps_rx_buffer[gps_rx_wr_index] = data;
		if (++gps_rx_wr_index == GPS_RX_BUFFER_SIZE) gps_rx_wr_index = 0;
		if (++gps_rx_counter == GPS_RX_BUFFER_SIZE)
		{
			gps_rx_counter = 0;
			gps_rx_buffer_overflow = 1;
		}
	}
}

void UART_GPS_SendByte(uint8_t data)
{
	USART_SendData(COM_GPS, data);
	while(USART_GetFlagStatus(COM_GPS, USART_FLAG_TXE) == RESET);
}

void UART_GPS_SendString(unsigned char *data)
{
	while(*data != NULL){
		UART_GPS_SendByte(*data);
		data++;
	}
}

uint8_t UART_GPS_ReceivedByte(void)
{
	uint8_t data;
	while (gps_rx_counter == 0);
	data = gps_rx_buffer[gps_rx_rd_index];
	if (++gps_rx_rd_index == GPS_RX_BUFFER_SIZE) gps_rx_rd_index=0;
	--gps_rx_counter;
	return data;
}


void UART_GPS_ReceivedString(uint8_t *data_buff, uint8_t data_len)
{
	uint8_t i;
	for(i=0;i<data_len;i++){
		data_buff[i] = UART_GPS_ReceivedByte();
	}
}

uint8_t UART_GPS_RXAvailable(void)
{
	return gps_rx_counter;
}

void UART_GPS_RXFlush(void)
{
	while(UART_GPS_RXAvailable()){
		UART_GPS_ReceivedByte();			//dummy read
	}
}
